package pe.gob.foncodes.ssa.bs.seguridad.dao.impl;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import pe.gob.foncodes.ssa.bs.common.dao.impl.GenericDaoJpa;
import pe.gob.foncodes.ssa.bs.common.util.Constante;
import pe.gob.foncodes.ssa.bs.common.util.DaoException;
import pe.gob.foncodes.ssa.bs.seguridad.dao.UsuarioDao;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Accion;
import pe.gob.foncodes.ssa.bs.seguridad.domain.HorarioPerfil;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Modulo;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Opcion;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Usuario;

public class UsuarioDaoJpa extends GenericDaoJpa implements UsuarioDao   {

    @Override
    public List<Opcion> getFirstLevelNodes(Long idUsuario, List<Long> usuarioPerfilList) throws DaoException {
        List<Opcion> lista = new ArrayList<Opcion>();
        String jpql="SELECT DISTINCT o FROM Usuario u JOIN u.usuarioPerfilList up  "
                + "JOIN up.usuarioAutorizacionList ua JOIN ua.accion a JOIN a.nidOpcion o "
                + "WHERE ua.flgActivo ='"+Constante.ESTADO_ACTIVO+"' AND a.flgActivo = '"+Constante.ESTADO_ACTIVO+"' AND o.flgActivo = '"+Constante.ESTADO_ACTIVO+"' "
                + "AND a.flgDefault = '1' AND o.nidOpcionPadre IS NULL AND u.id=?1 AND up.id in (?2) AND o.nidModulo.id = 0 "
                + "ORDER BY o.numOrden ASC";
        lista = getJpaTemplate().find(jpql, new Object[]{idUsuario, usuarioPerfilList});
        return lista;
    }
    
    @Override
    public List<Opcion> getFirstLevelNodes(Long idUsuario, Long idModulo, String codZonal) throws DaoException {
        List<Opcion> lista = new ArrayList<Opcion>();
        String jpql="SELECT DISTINCT o"
                    + " FROM Usuario u"
                    + " JOIN u.usuarioPerfilList up"
                    + " JOIN up.usuarioAutorizacionList ua"
                    + " JOIN ua.accion a"
                    + " JOIN a.nidOpcion o"
                    + " JOIN o.nidModulo mo"
                    + " WHERE ua.flgActivo = '"+Constante.ESTADO_ACTIVO+"'"
                    + " AND a.flgActivo = '"+Constante.ESTADO_ACTIVO+"'"
                    + " AND o.flgActivo = '"+Constante.ESTADO_ACTIVO+"'"
                    + " AND o.nidOpcionPadre IS NULL"
                    + " AND u.id = ?1"
                    + " AND mo.id = ?2"
                    + " AND up.codZonal = ?3"
                    + " ORDER BY o.numOrden ASC";
        lista = getJpaTemplate().find(jpql, new Object[]{idUsuario, idModulo, codZonal});
        return lista;
    }

    @Override
    public List<Accion> getOtherLevelNodes(Long idNodeSup, Long idUsuario, List<Long> usuarioPerfilList, String codZonal) throws DaoException {
        List<Accion> lista = new ArrayList<Accion>();
        List<Object[]> listaObj = new ArrayList<Object[]>();
        String jpql="SELECT DISTINCT a, o.numOrden FROM Usuario u JOIN u.usuarioPerfilList up JOIN up.nidPerfil p "
                + "JOIN up.usuarioAutorizacionList ua JOIN ua.accion a JOIN a.nidOpcion o JOIN o.nidOpcionPadre op "
                + "WHERE ua.flgActivo ='"+Constante.ESTADO_ACTIVO+"' AND a.flgActivo = '"+Constante.ESTADO_ACTIVO+"' AND o.flgActivo = '"+Constante.ESTADO_ACTIVO+"' "
                + "AND op.id = ?1 AND u.id= ?2 AND up.codZonal = ?3 AND a.flgDefault='1' "
                + "ORDER BY o.numOrden ASC";
        //up.id in (?3)
        listaObj = getJpaTemplate().find(jpql, new Object[]{idNodeSup, idUsuario, codZonal});
        for (Object[] obj : listaObj) {
            lista.add((Accion) obj[0]);
        }
        return lista;
    }
    
    @Override
    public List<Accion> getOtherLevelNodes(Long idNodeSup, Long idUsuario, String codZonal) throws DaoException {
        List<Accion> lista = new ArrayList<Accion>();
        String jpql="SELECT DISTINCT a"
                    + " FROM Usuario u"
                    + " JOIN u.usuarioPerfilList up"
                    + " JOIN up.nidPerfil p"
                    + " JOIN up.usuarioAutorizacionList ua"
                    + " JOIN ua.accion a"
                    + " JOIN a.nidOpcion o"
                    + " JOIN o.nidOpcionPadre op"
                    + " WHERE ua.flgActivo ='"+Constante.ESTADO_ACTIVO+"'"
                    + " AND a.flgActivo = '"+Constante.ESTADO_ACTIVO+"'"
                    + " AND o.flgActivo = '"+Constante.ESTADO_ACTIVO+"'"
                    + " AND op.id = ?1"
                    + " AND u.id= ?2"
                    + " AND up.codZonal = ?3"
                    + " ORDER BY o.numOrden ASC";
        lista = getJpaTemplate().find(jpql, new Object[]{idNodeSup, idUsuario, codZonal});
        return lista;
    }

    @Override
    public String retornaClaveEncriptada(String txtClave, String codUsuario) throws DaoException {
        String enc_clave ="";
        String sql = "SELECT ssa.sf_codificacion('"+txtClave+"','"+codUsuario+"') FROM dual";
        Object obj=createNativeQuery(sql);
        if(obj!=null){
            enc_clave = obj.toString();
        }
        return enc_clave;
    }

    @Override
    public List<HorarioPerfil> retornaHorarioPorPerfiles(List<Long> usuarioPerfilList, String estado) throws DaoException {
        List<HorarioPerfil> lista = findByNamedQuery("HorarioPerfil.findByNIdUsuarioPerfil", new Object[]{usuarioPerfilList, estado});
        return lista;
    }
    
    @Override
    public List<Usuario> getUsuarioByUnidadTerritorialZonalUsuario(String codZonal, String codUnidad, String codUsuario) throws DaoException{
        List<Usuario> lista = new ArrayList<Usuario>();
        StringWriter jpql = new StringWriter();
        String jpqlWhere ="";
        String jpqlFrom  =" Usuario u";
        if (codZonal !=null){
            jpqlFrom += " , Zonal z";
            jpqlWhere = " AND u.codZonal = z.codZonal AND z.codZonal = '" + codZonal + "'";
            if (codZonal.equals(Constante.CODIGO_SEDE_CENTRAL) && codUnidad !=null){
                jpqlFrom += " ,Personal p";
                jpqlWhere += " AND u.nidPersonal = p.nidPersonal AND p.codUnidad = '"+ codUnidad + "'";
            }
        }
        jpql.append (" SELECT DISTINCT u FROM " + jpqlFrom);
        jpql.append (" WHERE 0=0 " + jpqlWhere);
        //jpql.append ( (codZonal!=null?" AND z.codZonal = '"+codZonal+"'":""));
        //jpql.append ( (codZonal!=null && codZonal.equals(Constante.CODIGO_SEDE_CENTRAL) && codUnidad !=null?" AND p.codUnidad ='"+codUnidad+"'":""));
        jpql.append ( (codUsuario!=null && !codUsuario.trim().equals("") ?" AND UPPER(u.codUsuario) LIKE '%"+codUsuario.toUpperCase()+"%'":" "));
        if(!codUsuario.equals("")){
            jpql.append (" OR UPPER(CONCAT(u.txtApellidoPaterno, ' ', u.txtApellidoMaterno, ' ', u.txtNombres)) LIKE '%"+codUsuario.toUpperCase()+"%' ");
        }
        lista = getJpaTemplate().find(jpql.toString());
        return lista;
    }

    @Override
    public Modulo getModuloPadre(Long nidModulo) throws DaoException {
        Modulo modulo = null;
        String sql = "";
        sql  = " SELECT MIN(PARENT_ID) AS INICIO FROM ( ";
        sql += " SELECT T1.NID_MODULO, T1.NID_MODULO_PADRE, T1.TXT_MODULO AS TXT_MODULO_PADRE, ";        
        sql += " T2.TXT_MODULO AS PARENT_NAME, T2.NID_MODULO AS PARENT_ID FROM SSA.MODULO T1 ";
        sql += " LEFT JOIN SSA.MODULO T2 ON T2.NID_MODULO = T1.NID_MODULO_PADRE ";
        sql += " START WITH T1.NID_MODULO = "+nidModulo+" CONNECT BY T1.NID_MODULO = PRIOR T1.NID_MODULO_PADRE) ";
        Long nidFoundModulo = null;
        List<Object> lista = createNativeQuery(sql,new Object[]{nidModulo});
        if(!lista.isEmpty()){
            nidFoundModulo = Long.parseLong(lista.get(0).toString());
            if(nidFoundModulo != null){
                modulo = (Modulo) findById(Modulo.class, nidFoundModulo);
            }
        }
        return modulo;
    }   
}
